home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / util / boot / nloadwb.lha / NewLoadWB.c < prev    next >
C/C++ Source or Header  |  1995-04-11  |  5KB  |  226 lines

  1. /* NewLoadWB © 1995 Elaborate Bytes, Oliver Kastl
  2.     Hides DOS devices to be seen by the Workbench */
  3.  
  4.  
  5. #include <stdarg.h>
  6. #include <string.h>
  7.  
  8. /* Globals */
  9.  
  10. struct Library *DOSBase=NULL;
  11. struct ExecBase *SysBase;
  12.  
  13. #define TEMPLATE "ALL/S,QUIET/S,DOSDEV/M"
  14. #define OPT_ALL 0
  15. #define OPT_QUIET 1
  16. #define OPT_DOSDEV 2
  17. #define OPT_COUNT 3
  18.  
  19. LONG opts[OPT_COUNT];
  20.  
  21. /* Our private device list */
  22.  
  23. struct List DevList;
  24.  
  25. /* Protos */
  26.  
  27. void RemoveDosEntry(UBYTE *name);
  28. void RestoreDosEntries(void);
  29. void RemoveDosEntries(void);
  30. void MyPrintf (char *format, ...);
  31.  
  32. /* This is the first address of the program. We do NOT use any
  33.     startup code to keep this thingy dingy small.
  34.     This program will surely crash if started from Workbench.
  35.     Is there any reason to start a LoadWB from Workbench?
  36.     This could be a philosophical discussion during the next decade,
  37.     I suppose. 
  38. */
  39.  
  40. long __saveds main(void)
  41.     {
  42.     long result;
  43.     
  44.     /* Yippee! The name of the command to start during the DOS devices are
  45.         removed. The "Delay" keyword is important, otherwise we would restore
  46.         the DOS list too early!! */
  47.         
  48.     UBYTE *command="C:LoadWB DELAY";
  49.     
  50.      SysBase = (*((struct ExecBase **)4));
  51.  
  52.     if(DOSBase=OpenLibrary("dos.library\0$VER: NewLoadWB 1.1 (10.04.95)",37))
  53.         {
  54.         struct RDArgs *ra;
  55.         if(ra=ReadArgs(TEMPLATE,opts,NULL))
  56.             {
  57.             /* Initialize our private list */
  58.  
  59.             NewList(&DevList);
  60.  
  61.             if(opts[OPT_ALL])
  62.                 {
  63.                 RemoveDosEntries();
  64.                 }
  65.             else if(opts[OPT_DOSDEV])
  66.                 {
  67.                 UBYTE **arg=(UBYTE **)opts[OPT_DOSDEV];
  68.                 while(*arg)
  69.                     {
  70.                     RemoveDosEntry(*arg++);
  71.                     }
  72.                 }
  73.  
  74.             if(SystemTagList(command,NULL))
  75.                 {
  76.                 result=5;
  77.                 MyPrintf("Can't start %s!\n", command);
  78.                 }
  79.             else
  80.                 {
  81.                 result=0;
  82.                 }    
  83.             RestoreDosEntries();
  84.             FreeArgs(ra);
  85.             }
  86.         else
  87.             {
  88.             PrintFault(IoErr(),NULL);
  89.             result=10;
  90.             }
  91.         CloseLibrary(DOSBase);
  92.         }
  93.     else result=20;
  94.     return result;
  95.     }
  96.  
  97.  
  98. BOOL IsRemoveCandidate(struct DosList *dlist)
  99.     {
  100.     /* Check if the handler has been started already.
  101.         If not, it is no valid candidate, as Workbench will ignore
  102.         this entry anyway.
  103.  
  104.         IMPORTANT!!! 
  105.         Avoids handlers to be started by the IsFileSystem() call!
  106.         This would cause the system to deadlock!! */
  107.  
  108.     if(dlist->dol_misc.dol_handler.dol_SegList)
  109.         {
  110.         UBYTE name[32];
  111.         UBYTE *candidate=BADDR(dlist->dol_Name);
  112.  
  113.         /* Build a proper name for IsFileSystem() */
  114.  
  115.         /* Convert BSTR */
  116.         memcpy(name,candidate+1,*candidate);
  117.  
  118.         /* Add colon */
  119.         name[*candidate]=':';
  120.         
  121.         /* Terminate CSTR */
  122.         name[*candidate+1]=0;
  123.  
  124.         /* Only remove Filesystems */
  125.         /* DANGER! This sends a packet to the handler during
  126.             LockDosList()! Shouldn't be a problem, as the handler
  127.             has been started already... */
  128.  
  129.         return(IsFileSystem(name));
  130.         }
  131.     return(FALSE);
  132.     }
  133.     
  134.  
  135.  
  136. /* Remove a DOS device specified by name from the DOS device list.
  137.     Add it in our private list for later reinsertion. */
  138.  
  139. void RemoveDosEntry(UBYTE *name)
  140.     {
  141.     struct DosList *dlist;
  142.     struct Node *node;
  143.  
  144.     dlist=LockDosList(LDF_DEVICES|LDF_WRITE);
  145.     if(dlist=FindDosEntry(dlist, name, LDF_DEVICES))
  146.         {
  147.         if(IsRemoveCandidate(dlist))
  148.             {
  149.             if(node=AllocVec(sizeof(struct Node),MEMF_ANY))
  150.                 {
  151.                 RemDosEntry(dlist);
  152.                 node->ln_Name=(UBYTE *)dlist;
  153.                 AddHead(&DevList,node);
  154.                 }
  155.             }
  156.         else MyPrintf("WARNING: %s not removed!\n",name);
  157.         }
  158.     else MyPrintf("WARNING: %s not found!\n",name);
  159.  
  160.     UnLockDosList(LDF_DEVICES|LDF_WRITE);
  161.     }
  162.  
  163.  
  164. /* Remove all DOS devices that are valid candidates from the DOS device list.
  165.     Add them in our private list for later reinsertion. */
  166.  
  167. void RemoveDosEntries(void)
  168.     {
  169.     struct DosList *dlist;
  170.     struct Node *node;
  171.  
  172.     dlist=LockDosList(LDF_DEVICES|LDF_WRITE);
  173.  
  174.     /* Tricky! This works as the DOS device list is only a singly
  175.         linked list! */
  176.  
  177.     while(dlist=NextDosEntry(dlist, LDF_DEVICES))
  178.         {
  179.         if(IsRemoveCandidate(dlist))
  180.             {
  181.             if(node=AllocVec(sizeof(struct Node),MEMF_ANY))
  182.                 {
  183.                 RemDosEntry(dlist);
  184.  
  185.                 /* As I am a lazy programmer, I use the ln_Name field
  186.                     to store the entry. Good style would be the definition
  187.                     of a struct MyDevListNode bla, bla, bla... */
  188.                     
  189.                 node->ln_Name=(UBYTE *)dlist;
  190.                 AddHead(&DevList,node);
  191.                 }
  192.             }
  193.         }
  194.  
  195.     UnLockDosList(LDF_DEVICES|LDF_WRITE);
  196.     }
  197.  
  198.  
  199. /* Scan our private list and reinsert all removed DOS devices into the
  200.     DOS list */
  201.  
  202. void RestoreDosEntries(void)
  203.     {
  204.     struct Node *node;
  205.  
  206.     LockDosList(LDF_DEVICES|LDF_WRITE);
  207.  
  208.     while(node=RemHead(&DevList))
  209.         {
  210.         AddDosEntry((struct DosList *)node->ln_Name);
  211.         FreeVec(node);
  212.         }
  213.  
  214.     UnLockDosList(LDF_DEVICES|LDF_WRITE);
  215.     }
  216.  
  217. void MyPrintf (char *format, ...)
  218.     {
  219.     va_list arg;
  220.  
  221.     va_start (arg, format);
  222.     if(!opts[OPT_QUIET])
  223.         VPrintf (format, arg);
  224.     va_end (format);
  225.     }
  226.